﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;

namespace SecureGRF
{
    public partial class FormProfile : Form
    {
        public FormProfile()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            openFileDialog1.FileName = textBox1.Text;
            if (openFileDialog1.ShowDialog() != DialogResult.OK) return;
            textBox1.Text = openFileDialog1.FileName;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            folderBrowserDialog1.SelectedPath = textBox4.Text;
            if (folderBrowserDialog1.ShowDialog() != DialogResult.OK) return;
            textBox4.Text = folderBrowserDialog1.SelectedPath;
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (!CheckParameter()) return;
            EnableControl(false);
            lblWorking.Visible = true;
            ConfigureProfile profile = new ConfigureProfile();
            DoConfigureDelegate doConfigure = new DoConfigureDelegate(profile.DoConfigure);
            doConfigure.BeginInvoke(textBox1.Text, textBox2.Text, textBox3.Text, textBox4.Text, new AsyncCallback(DoConfigureCallback), doConfigure);
        }

        private void button4_Click(object sender, EventArgs e)
        {
            if (!Directory.Exists(textBox4.Text)) return;
            ProcessStartInfo psi = new ProcessStartInfo(textBox4.Text);
            psi.UseShellExecute = true;
            psi.Verb = "open";
            Process.Start(psi);
        }

        private bool CheckParameter()
        {
            try
            {
                if (!File.Exists(textBox1.Text)) throw new Exception("Please select a client executable file!");
                if (textBox2.Text.Length == 0) throw new Exception("Please enter the kernel lib filename!");
                if (Encoding.Default.GetByteCount(textBox2.Text) > 7) throw new Exception("Kernel lib filename won't be longer than 7 bytes!");
                if (textBox3.Text.Length == 0) throw new Exception("Please enter the password!");
                if (!Directory.Exists(textBox4.Text)) throw new Exception("Please select an output directory!");
                if (Path.GetDirectoryName(textBox1.Text).ToLower() == textBox4.Text.ToLower() ||
                    Path.GetDirectoryName(Application.ExecutablePath).ToLower() == textBox4.Text.ToLower())
                    throw new Exception("The output directory won't be the directory of client executable file or the directory of the Secure GRF program!");
                return true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return false;
            }
        }

        private delegate string DoConfigureDelegate(string clientFile, string kernelFile, string password, string outputPath);

        private void DoConfigureCallback(IAsyncResult ar)
        {
            if (InvokeRequired)
            {
                Invoke(new AsyncCallback(DoConfigureCallback), ar);
                return;
            }
            if (ar.IsCompleted)
            {
                DoConfigureDelegate doConfigure = (DoConfigureDelegate)ar.AsyncState;
                string ret = doConfigure.EndInvoke(ar);
                lblWorking.Visible = false;
                EnableControl(true);
                if (ret.StartsWith("1"))
                    MessageBox.Show(ret.Remove(0, 1), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
                else MessageBox.Show(ret.Remove(0, 1), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void EnableControl(bool enabled)
        {
            textBox1.ReadOnly = !enabled;
            button1.Enabled = enabled;
            textBox2.ReadOnly = !enabled;
            textBox3.ReadOnly = !enabled;
            textBox4.ReadOnly = !enabled;
            button2.Enabled = enabled;
            button3.Enabled = enabled;
        }
    }
}
